home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / fspdev / fspdevControl.c < prev    next >
C/C++ Source or Header  |  1991-06-26  |  21KB  |  681 lines

  1. /* 
  2.  * fsPdev.c --  
  3.  *
  4.  * Copyright 1987, 1988 Regents of the University of California
  5.  * Permission to use, copy, modify, and distribute this
  6.  * software and its documentation for any purpose and without
  7.  * fee is hereby granted, provided that the above copyright
  8.  * notice appear in all copies.  The University of California
  9.  * makes no representations about the suitability of this
  10.  * software for any purpose.  It is provided "as is" without
  11.  * express or implied warranty.
  12.  */
  13.  
  14. #ifndef lint
  15. static char rcsid[] = "$Header: /sprite/src/kernel/fspdev/RCS/fspdevControl.c,v 9.3 91/06/26 01:07:12 mottsmth Exp $ SPRITE (Berkeley)";
  16. #endif not lint
  17.  
  18. #include <sprite.h>
  19. #include <fs.h>
  20. #include <fsconsist.h>
  21. #include <fsutil.h>
  22. #include <fspdev.h>
  23. #include <fspdevInt.h>
  24. #include <fsNameOps.h>
  25. #include <fsio.h>
  26. #include <fsioLock.h>
  27. #include <fsStat.h>
  28. #include <proc.h>
  29. #include <rpc.h>
  30.  
  31. /*
  32.  *----------------------------------------------------------------------------
  33.  *
  34.  * FspdevControlHandleInit --
  35.  *
  36.  *    Fetch and initialize a control handle for a pseudo-device.
  37.  *
  38.  * Results:
  39.  *    A pointer to the control stream I/O handle.  The found parameter is
  40.  *    set to TRUE if the handle was already found, FALSE if we created it.
  41.  *
  42.  * Side effects:
  43.  *    Initializes and installs the control handle.
  44.  *
  45.  *----------------------------------------------------------------------------
  46.  *
  47.  */
  48. Fspdev_ControlIOHandle *
  49. FspdevControlHandleInit(fileIDPtr, name)
  50.     Fs_FileID *fileIDPtr;
  51.     char *name;
  52. {
  53.     register Boolean found;
  54.     register Fspdev_ControlIOHandle *ctrlHandlePtr;
  55.     Fs_HandleHeader *hdrPtr;
  56.  
  57.     found = Fsutil_HandleInstall(fileIDPtr, sizeof(Fspdev_ControlIOHandle), name,
  58.                 FALSE, &hdrPtr);
  59.     ctrlHandlePtr = (Fspdev_ControlIOHandle *)hdrPtr;
  60.     if (!found) {
  61.     ctrlHandlePtr->serverID = NIL;
  62.     List_Init(&ctrlHandlePtr->queueHdr);
  63.     ctrlHandlePtr->seed = 0;
  64.     List_Init(&ctrlHandlePtr->readWaitList);
  65.     Fsio_LockInit(&ctrlHandlePtr->lock);
  66.     Fsutil_RecoveryInit(&ctrlHandlePtr->rmt.recovery);
  67.     ctrlHandlePtr->accessTime = 0;
  68.     ctrlHandlePtr->modifyTime = 0;
  69.     ctrlHandlePtr->owner.id = (Proc_PID)NIL;
  70.     ctrlHandlePtr->owner.procOrFamily = 0;
  71.     ctrlHandlePtr->prefixPtr = (Fsprefix *)NIL;
  72.     fs_Stats.object.controls++;
  73.     }
  74.     return(ctrlHandlePtr);
  75. }
  76.  
  77. /*
  78.  *----------------------------------------------------------------------
  79.  *
  80.  * FspdevControlIoOpen --
  81.  *
  82.  *    Complete setup of the server's control stream.  Called from
  83.  *    Fs_Open on the host running the server.  We mark the Control
  84.  *    I/O handle as having a server (us).
  85.  * 
  86.  * Results:
  87.  *    SUCCESS.
  88.  *
  89.  * Side effects:
  90.  *    Installs the Control I/O handle and keeps a reference to it.
  91.  *    Marks the process as not suitable for migration.
  92.  *
  93.  *----------------------------------------------------------------------
  94.  */
  95. /*ARGSUSED*/
  96. ReturnStatus
  97. FspdevControlIoOpen(ioFileIDPtr, flagsPtr, clientID, streamData, name,
  98.          ioHandlePtrPtr)
  99.     register Fs_FileID    *ioFileIDPtr;    /* I/O fileID */
  100.     int            *flagsPtr;    /* FS_READ | FS_WRITE ... */
  101.     int            clientID;    /* Host doing the open */
  102.     ClientData        streamData;    /* NIL. */
  103.     char        *name;        /* File name for error msgs */
  104.     Fs_HandleHeader    **ioHandlePtrPtr;/* Return - a locked handle set up for
  105.                      * I/O to a control stream, or NIL */
  106. {
  107.     register Fspdev_ControlIOHandle    *ctrlHandlePtr;
  108.  
  109.     ctrlHandlePtr = FspdevControlHandleInit(ioFileIDPtr, name);
  110.     if (!List_IsEmpty(&ctrlHandlePtr->queueHdr)) {
  111.     panic( "FsControlStreamCltOpen found control msgs\n");
  112.     }
  113.     ctrlHandlePtr->serverID = clientID;
  114.     *ioHandlePtrPtr = (Fs_HandleHeader *)ctrlHandlePtr;
  115.     /*
  116.      * Can't migrate pseudo-device servers.
  117.      */
  118.     Proc_NeverMigrate(Proc_GetCurrentProc());
  119.     Fsutil_HandleUnlock(ctrlHandlePtr);
  120.     return(SUCCESS);
  121. }
  122.  
  123. /*
  124.  *----------------------------------------------------------------------
  125.  *
  126.  * FspdevControlSelect --
  127.  *
  128.  *    Select on the server's control stream.  This returns readable
  129.  *    if there are control messages in the queue.
  130.  *
  131.  * Results:
  132.  *    SUCCESS.
  133.  *
  134.  * Side effects:
  135.  *    Puts the caller on the handle's read wait list if the control
  136.  *    stream isn't selectable.
  137.  *
  138.  *----------------------------------------------------------------------
  139.  */
  140.  
  141. ReturnStatus
  142. FspdevControlSelect(hdrPtr, waitPtr, readPtr, writePtr, exceptPtr)
  143.     Fs_HandleHeader    *hdrPtr;    /* Handle on device to select */
  144.     Sync_RemoteWaiter    *waitPtr;    /* Process info for remote waiting */
  145.     int         *readPtr;    /* Bit to clear if non-readable */
  146.     int         *writePtr;    /* Bit to clear if non-writeable */
  147.     int         *exceptPtr;    /* Bit to clear if non-exceptable */
  148. {
  149.     register Fspdev_ControlIOHandle *ctrlHandlePtr =
  150.         (Fspdev_ControlIOHandle *)hdrPtr;
  151.  
  152.     Fsutil_HandleLock(ctrlHandlePtr);
  153.     if (List_IsEmpty(&ctrlHandlePtr->queueHdr)) {
  154.     if (waitPtr != (Sync_RemoteWaiter *)NIL) {
  155.         Fsutil_FastWaitListInsert(&ctrlHandlePtr->readWaitList, waitPtr);
  156.     }
  157.     *readPtr = 0;
  158.     }
  159.     *writePtr = *exceptPtr = 0;
  160.     Fsutil_HandleUnlock(ctrlHandlePtr);
  161.     return(SUCCESS);
  162. }
  163.  
  164. /*
  165.  *----------------------------------------------------------------------
  166.  *
  167.  * FspdevControlRead --
  168.  *
  169.  *    Read from the server's control stream.  The server learns of new
  170.  *    clients by reading this stream.  Internally the stream is a list
  171.  *    of addresses of streams created for the server.  This routine maps
  172.  *    those addresses to streamIDs for the user level server process and
  173.  *    returns them to the reader.
  174.  *
  175.  * Results:
  176.  *    SUCCESS, FS_WOULD_BLOCK,
  177.  *    or an error code from setting up a new stream ID.
  178.  *
  179.  * Side effects:
  180.  *    The server's list of stream ptrs in the process table is updated.
  181.  *
  182.  *----------------------------------------------------------------------
  183.  */
  184. ReturnStatus
  185. FspdevControlRead(streamPtr, readPtr, waitPtr, replyPtr)
  186.     Fs_Stream         *streamPtr;    /* Control stream */
  187.     Fs_IOParam        *readPtr;    /* Read parameter block. */
  188.     Sync_RemoteWaiter    *waitPtr;    /* Process info for remote waiting */
  189.     Fs_IOReply        *replyPtr;    /* Signal to return, if any,
  190.                      * plus the amount read. */
  191. {
  192.     ReturnStatus         status;
  193.     register Fspdev_ControlIOHandle *ctrlHandlePtr =
  194.         (Fspdev_ControlIOHandle *)streamPtr->ioHandlePtr;
  195.     Pdev_Notify            notify;        /* Message returned to
  196.                          * user-level server proc */
  197.  
  198.     Fsutil_HandleLock(ctrlHandlePtr);
  199.  
  200.     if (List_IsEmpty(&ctrlHandlePtr->queueHdr)) {
  201.     /*
  202.      * No control messages ready.
  203.      */
  204.     Fsutil_FastWaitListInsert(&ctrlHandlePtr->readWaitList, waitPtr);
  205.     replyPtr->length = 0;
  206.     status = FS_WOULD_BLOCK;
  207.     } else {
  208.     register FspdevNotify *notifyPtr;        /* Internal message */
  209.     notifyPtr = (FspdevNotify *)List_First(&ctrlHandlePtr->queueHdr);
  210.     List_Remove((List_Links *)notifyPtr);
  211.     notify.magic = PDEV_NOTIFY_MAGIC;
  212.     status = Fs_GetStreamID(notifyPtr->streamPtr, ¬ify.newStreamID);
  213.     if (status != SUCCESS) {
  214.         replyPtr->length = 0;
  215.     } else {
  216.         if (readPtr->flags & FS_USER) {
  217.         status = Vm_CopyOut(sizeof(notify), (Address) ¬ify,
  218.                     readPtr->buffer);
  219.         /*
  220.          * No need to close on error because the stream is already
  221.          * installed in the server process's state.  It'll be
  222.          * closed automatically when the server exits.
  223.          */
  224.         } else {
  225.         bcopy((Address)¬ify, readPtr->buffer, sizeof(notify));
  226.         }
  227.         replyPtr->length = sizeof(notify);
  228.     }
  229.     free((Address)notifyPtr);
  230.     }
  231.     Fsutil_HandleUnlock(ctrlHandlePtr);
  232.     return(status);
  233. }
  234.  
  235. /*
  236.  *----------------------------------------------------------------------
  237.  *
  238.  * FspdevControlIOControl --
  239.  *
  240.  *    IOControls for the control stream.
  241.  *
  242.  * Results:
  243.  *    An error code.
  244.  *
  245.  * Side effects:
  246.  *    Command dependent.
  247.  *
  248.  *----------------------------------------------------------------------
  249.  */
  250.  
  251. ReturnStatus
  252. FspdevControlIOControl(streamPtr, ioctlPtr, replyPtr)
  253.     Fs_Stream *streamPtr;        /* I/O handle */
  254.     Fs_IOCParam *ioctlPtr;        /* I/O Control parameter block */
  255.     Fs_IOReply *replyPtr;        /* Return length and signal */
  256. {
  257.     register Fspdev_ControlIOHandle *ctrlHandlePtr =
  258.         (Fspdev_ControlIOHandle *)streamPtr->ioHandlePtr;
  259.     register ReturnStatus status;
  260.  
  261.     if (ioctlPtr->format != mach_Format) {
  262.     panic("FsControlIOControl: wrong format\n");
  263.     }
  264.     switch(ioctlPtr->command) {
  265.     case IOC_PDEV_SIGNAL_OWNER:
  266.         status = FspdevSignalOwner(ctrlHandlePtr, ioctlPtr);
  267.         break;
  268.     case IOC_REPOSITION:
  269.         status = SUCCESS;
  270.         break;
  271.     case IOC_GET_FLAGS:
  272.         if (ioctlPtr->outBufSize >= sizeof(int)) {
  273.         *(int *)ioctlPtr->outBuffer = 0;
  274.         replyPtr->length = sizeof(int);    /* to quiet lint */
  275.         }
  276.         status = SUCCESS;
  277.         break;
  278.     case IOC_SET_FLAGS:
  279.     case IOC_SET_BITS:
  280.     case IOC_CLEAR_BITS:
  281.         status = SUCCESS;
  282.         break;
  283.     case IOC_TRUNCATE:
  284.         status = SUCCESS;
  285.         break;
  286.     case IOC_LOCK:
  287.     case IOC_UNLOCK:
  288.         Fsutil_HandleLock(ctrlHandlePtr);
  289.         status = Fsio_IocLock(&ctrlHandlePtr->lock, ioctlPtr,
  290.                 &streamPtr->hdr.fileID);
  291.         Fsutil_HandleUnlock(ctrlHandlePtr);
  292.         break;
  293.     case IOC_NUM_READABLE: {
  294.         register int bytesAvailable;
  295.  
  296.         if (ioctlPtr->outBufSize < sizeof(int)) {
  297.         return(GEN_INVALID_ARG);
  298.         }
  299.         Fsutil_HandleLock(ctrlHandlePtr);
  300.         if (List_IsEmpty(&ctrlHandlePtr->queueHdr)) {
  301.         bytesAvailable = 0;
  302.         } else {
  303.         bytesAvailable = sizeof(Pdev_Notify);
  304.         }
  305.         Fsutil_HandleUnlock(ctrlHandlePtr);
  306.         status = SUCCESS;
  307.         *(int *)ioctlPtr->outBuffer = bytesAvailable;
  308.         break;
  309.     }
  310.     case IOC_SET_OWNER:
  311.     case IOC_GET_OWNER:
  312.     case IOC_MAP:
  313.         status = GEN_NOT_IMPLEMENTED;
  314.         break;
  315.     case IOC_PREFIX:
  316.         status = SUCCESS;
  317.         break;
  318.     default:
  319.         status = GEN_INVALID_ARG;
  320.         break;
  321.     }
  322.     return(status);
  323. }
  324.  
  325. /*
  326.  *----------------------------------------------------------------------
  327.  *
  328.  * FspdevControlGetIOAttr --
  329.  *
  330.  *    Called from Fs_GetAttrStream to get the I/O attributes of a
  331.  *    pseudo-device.  The access and modify times of the pseudo-device
  332.  *    are obtained from the internal pdev state.
  333.  *
  334.  * Results:
  335.  *    SUCCESS.
  336.  *
  337.  * Side effects:
  338.  *    None.
  339.  *
  340.  *----------------------------------------------------------------------
  341.  */
  342. ReturnStatus
  343. FspdevControlGetIOAttr(fileIDPtr, clientID, attrPtr)
  344.     register Fs_FileID        *fileIDPtr;    /* Identfies pdev connection */
  345.     int                clientID;    /* Host ID of process asking
  346.                          * for the attributes */
  347.     register Fs_Attributes    *attrPtr;    /* Return - the attributes */
  348. {
  349.     Fspdev_ControlIOHandle        *ctrlHandlePtr;
  350.  
  351.     ctrlHandlePtr = Fsutil_HandleFetchType(Fspdev_ControlIOHandle, fileIDPtr);
  352.     if (ctrlHandlePtr == (Fspdev_ControlIOHandle *)NIL) {
  353.     printf( "FspdevControlGetIOAttr, no %s handle <%d,%x,%x> client %d\n",
  354.         Fsutil_FileTypeToString(fileIDPtr->type), fileIDPtr->serverID,
  355.         fileIDPtr->major, fileIDPtr->minor, clientID);
  356.     return(FS_FILE_NOT_FOUND);
  357.     }
  358.  
  359.     if (ctrlHandlePtr->accessTime > 0) {
  360.     attrPtr->accessTime.seconds = ctrlHandlePtr->accessTime;
  361.     }
  362.     if (ctrlHandlePtr->modifyTime > 0) {
  363.     attrPtr->dataModifyTime.seconds = ctrlHandlePtr->modifyTime;
  364.     }
  365.  
  366.     Fsutil_HandleRelease(ctrlHandlePtr, TRUE);
  367.     return(SUCCESS);
  368. }
  369.  
  370. /*
  371.  *----------------------------------------------------------------------
  372.  *
  373.  * FspdevControlSetIOAttr --
  374.  *
  375.  *    Set the IO attributes of a pseudo-device.
  376.  *
  377.  * Results:
  378.  *    An error code.
  379.  *
  380.  * Side effects:
  381.  *    Updates the access and modify times kept in the pdev state.
  382.  *
  383.  *----------------------------------------------------------------------
  384.  */
  385. ReturnStatus
  386. FspdevControlSetIOAttr(fileIDPtr, attrPtr, flags)
  387.     register Fs_FileID        *fileIDPtr;    /* Identfies pdev connection */
  388.     register Fs_Attributes    *attrPtr;    /* Return - the attributes */
  389.     int                flags;        /* Tells which attrs to set */
  390. {
  391.     Fspdev_ControlIOHandle        *ctrlHandlePtr;
  392.  
  393.     ctrlHandlePtr = Fsutil_HandleFetchType(Fspdev_ControlIOHandle, fileIDPtr);
  394.     if (ctrlHandlePtr == (Fspdev_ControlIOHandle *)NIL) {
  395.     printf( "FspdevControlSetIOAttr, no handle <%d,%d,%x,%x>\n",
  396.         fileIDPtr->serverID, fileIDPtr->type,
  397.         fileIDPtr->major, fileIDPtr->minor);
  398.     return(FS_FILE_NOT_FOUND);
  399.     }
  400.     if (flags & FS_SET_TIMES) {
  401.     ctrlHandlePtr->accessTime = attrPtr->accessTime.seconds;
  402.     ctrlHandlePtr->modifyTime = attrPtr->dataModifyTime.seconds;
  403.     }
  404.     Fsutil_HandleRelease(ctrlHandlePtr, TRUE);
  405.     return(SUCCESS);
  406. }
  407.  
  408. /*
  409.  *----------------------------------------------------------------------
  410.  *
  411.  * FspdevControlVerify --
  412.  *
  413.  *    This is called during recovery.
  414.  *    When the server at a remote site reopens its control stream it
  415.  *    contacts the file server to re-establish itself as the server.
  416.  *    This procedure is called from Fsio_StreamReopen to get the control
  417.  *    handle associated with the top-level shadow stream here at the
  418.  *    file server.
  419.  *
  420.  * Results:
  421.  *    A pointer to the control I/O handle, or NIL if the server is bad.
  422.  *
  423.  * Side effects:
  424.  *    The handle is returned locked and with its refCount incremented.
  425.  *    It should be released with Fsutil_HandleRelease.
  426.  *
  427.  *----------------------------------------------------------------------
  428.  */
  429.  
  430. Fs_HandleHeader *
  431. FspdevControlVerify(fileIDPtr, pdevServerHostID, domainTypePtr)
  432.     Fs_FileID    *fileIDPtr;        /* control I/O file ID */
  433.     int        pdevServerHostID;    /* Host ID of the client */
  434.     int         *domainTypePtr;     /* Return - FS_PSEUDO_DOMAIN */
  435. {
  436.     register Fspdev_ControlIOHandle    *ctrlHandlePtr;
  437.     int serverID = -1;
  438.  
  439.     ctrlHandlePtr = Fsutil_HandleFetchType(Fspdev_ControlIOHandle, fileIDPtr);
  440.     if (ctrlHandlePtr != (Fspdev_ControlIOHandle *)NIL) {
  441.     if (ctrlHandlePtr->serverID != pdevServerHostID) {
  442.         serverID = ctrlHandlePtr->serverID;
  443.         Fsutil_HandleRelease(ctrlHandlePtr, TRUE);
  444.         ctrlHandlePtr = (Fspdev_ControlIOHandle *)NIL;
  445.     }
  446.     }
  447.     if (ctrlHandlePtr == (Fspdev_ControlIOHandle *)NIL) {
  448.     printf("FspdevControlVerify, server mismatch (%d not %d) for %s <%x,%x>\n",
  449.         pdevServerHostID, serverID, Fsutil_FileTypeToString(fileIDPtr->type),
  450.         fileIDPtr->major, fileIDPtr->minor);
  451.     }
  452.     if (domainTypePtr != (int *)NIL) {
  453.     *domainTypePtr = FS_PSEUDO_DOMAIN;
  454.     }
  455.     return((Fs_HandleHeader *)ctrlHandlePtr);
  456. }
  457.  
  458. /*
  459.  *----------------------------------------------------------------------
  460.  *
  461.  * FspdevControlReopen --
  462.  *
  463.  *    Reopen a control stream.  A control handle is kept on both the
  464.  *    file server as well as the pseudo-device server's host.  If the
  465.  *    file server reboots a reopen has to be done in order to set
  466.  *    the serverID field on the file server so subsequent client opens work.
  467.  *    Thus this is called on a remote client to contact the file server,
  468.  *    and then on the file server from the RPC stub.
  469.  *
  470.  * Results:
  471.  *    SUCCESS if there is no conflict with the server reopening.
  472.  *
  473.  * Side effects:
  474.  *    On the file server the serverID field is set.
  475.  *
  476.  *----------------------------------------------------------------------
  477.  */
  478. /*ARGSUSED*/
  479. ReturnStatus
  480. FspdevControlReopen(hdrPtr, clientID, inData, outSizePtr, outDataPtr)
  481.     Fs_HandleHeader    *hdrPtr;
  482.     int            clientID;        /* ID of pdev server's host */
  483.     ClientData        inData;            /* FspdevControlReopenParams */
  484.     int            *outSizePtr;        /* IGNORED */
  485.     ClientData        *outDataPtr;        /* IGNORED */
  486.  
  487. {
  488.     register Fspdev_ControlIOHandle *ctrlHandlePtr;
  489.     register FspdevControlReopenParams *reopenParamsPtr;
  490.     register ReturnStatus status = SUCCESS;
  491.  
  492.     if (hdrPtr != (Fs_HandleHeader *)NIL) {
  493.     /*
  494.      * Called on the pdev server's host to contact the remote
  495.      * file server and re-establish state.
  496.      */
  497.     Fspdev_ControlIOHandle *ctrlHandlePtr;
  498.     FspdevControlReopenParams params;
  499.     int outSize = 0;
  500.  
  501.     ctrlHandlePtr = (Fspdev_ControlIOHandle *)hdrPtr;
  502.     reopenParamsPtr = ¶ms;
  503.     reopenParamsPtr->fileID = hdrPtr->fileID;
  504.     reopenParamsPtr->serverID = ctrlHandlePtr->serverID;
  505.     reopenParamsPtr->seed = ctrlHandlePtr->seed;
  506.     status = FsrmtReopen(hdrPtr, sizeof(FspdevControlReopenParams),
  507.         (Address)reopenParamsPtr, &outSize, (Address)NIL);
  508.     } else {
  509.     /*
  510.      * Called on the file server to re-establish a control handle
  511.      * that corresponds to a control handle on the pdev server's host.
  512.      */
  513.  
  514.     reopenParamsPtr = (FspdevControlReopenParams *)inData;
  515.     ctrlHandlePtr = FspdevControlHandleInit(&reopenParamsPtr->fileID,
  516.                         (char *)NIL);
  517.     if (reopenParamsPtr->serverID != NIL) {
  518.         /*
  519.          * The remote host thinks it is running the pdev server process.
  520.          */
  521.         if (ctrlHandlePtr->serverID == NIL) {
  522.         ctrlHandlePtr->serverID = reopenParamsPtr->serverID;
  523.         ctrlHandlePtr->seed = reopenParamsPtr->seed;
  524.         } else if (ctrlHandlePtr->serverID != clientID) {
  525.         printf(
  526.             "PdevControlReopen conflict, %d lost to %d, %s <%x,%x>\n",
  527.             clientID, ctrlHandlePtr->serverID,
  528.             Fsutil_FileTypeToString(ctrlHandlePtr->rmt.hdr.fileID.type),
  529.             ctrlHandlePtr->rmt.hdr.fileID.major,
  530.             ctrlHandlePtr->rmt.hdr.fileID.minor);
  531.         status = FS_FILE_BUSY;
  532.         }
  533.     } else if (ctrlHandlePtr->serverID == clientID) {
  534.         /*
  535.          * The pdev server closed while we were down or unable
  536.          * to communicate.
  537.          */
  538.         ctrlHandlePtr->serverID = NIL;
  539.     }
  540.     Fsutil_HandleRelease(ctrlHandlePtr, TRUE);
  541.      }
  542.     return(status);
  543. }
  544.  
  545. /*
  546.  *----------------------------------------------------------------------
  547.  *
  548.  * FspdevControlClose --
  549.  *
  550.  *    Close a server process's control stream.  After this the pseudo-device
  551.  *    is no longer active and client operations will fail.
  552.  *
  553.  * Results:
  554.  *    SUCCESS.
  555.  *
  556.  * Side effects:
  557.  *    Reset the control handle's serverID.
  558.  *    Clears out the state for the control message queue.
  559.  *
  560.  *----------------------------------------------------------------------
  561.  */
  562. /*ARGSUSED*/
  563. #ifdef SOSP91
  564. ReturnStatus
  565. FspdevControlClose(streamPtr, clientID, procID, flags, size, data, offsetPtr,
  566.     rwFlagsPtr)
  567. #else
  568. ReturnStatus
  569. FspdevControlClose(streamPtr, clientID, procID, flags, size, data)
  570. #endif
  571.     Fs_Stream        *streamPtr;    /* Control stream */
  572.     int            clientID;    /* HostID of client closing */
  573.     Proc_PID        procID;        /* ID of closing process */
  574.     int            flags;        /* Flags from the stream being closed */
  575.     int            size;        /* Should be zero */
  576.     ClientData        data;        /* IGNORED */
  577. #ifdef SOSP91
  578.     int            *offsetPtr;    /* Not used. */
  579.     int            *rwFlagsPtr;    /* Not used. */
  580. #endif
  581. {
  582.     register Fspdev_ControlIOHandle *ctrlHandlePtr =
  583.         (Fspdev_ControlIOHandle *)streamPtr->ioHandlePtr;
  584.     register FspdevNotify *notifyPtr;
  585.     int extra = 0;
  586.  
  587.     /*
  588.      * Close any server streams that haven't been given to
  589.      * the master process yet.
  590.      */
  591.     while (!List_IsEmpty(&ctrlHandlePtr->queueHdr)) {
  592.     notifyPtr = (FspdevNotify *)List_First(&ctrlHandlePtr->queueHdr);
  593.     List_Remove((List_Links *)notifyPtr);
  594.     extra++;
  595.     (void)Fs_Close(notifyPtr->streamPtr);
  596.     free((Address)notifyPtr);
  597.     }
  598.     if (extra) {
  599.     printf( "FspdevControlClose found %d left over messages\n",
  600.             extra);
  601.     }
  602.     /*
  603.      * Reset the pseudo-device server ID, both here and at the name server.
  604.      */
  605.     ctrlHandlePtr->serverID = NIL;
  606.     if (ctrlHandlePtr->rmt.hdr.fileID.serverID != rpc_SpriteID) {
  607.     (void)Fsrmt_Close(streamPtr, rpc_SpriteID, procID, 0, 0,
  608.         (ClientData)NIL);
  609.     }
  610.     Fsutil_WaitListDelete(&ctrlHandlePtr->readWaitList);
  611.     Fsutil_HandleRelease(ctrlHandlePtr, TRUE);
  612.     return(SUCCESS);
  613. }
  614.  
  615. /*
  616.  *----------------------------------------------------------------------
  617.  *
  618.  * FspdevControlClientKill --
  619.  *
  620.  *    See if a crashed client was running a pseudo-device master.
  621.  *
  622.  * Results:
  623.  *    None.
  624.  *
  625.  * Side effects:
  626.  *    Clears the serverID field if it matches the crashed host's ID.
  627.  *    This unlocks the handle before returning.
  628.  *
  629.  *----------------------------------------------------------------------
  630.  */
  631. /*ARGSUSED*/
  632. void
  633. FspdevControlClientKill(hdrPtr, clientID)
  634.     Fs_HandleHeader *hdrPtr;    /* File being killed */
  635.     int        clientID;    /* Client ID to kill. */
  636. {
  637.     register Fspdev_ControlIOHandle *ctrlHandlePtr =
  638.         (Fspdev_ControlIOHandle *)hdrPtr;
  639.  
  640.     if (ctrlHandlePtr->serverID == clientID) {
  641.     ctrlHandlePtr->serverID = NIL;
  642.     Fsutil_RecoverySyncLockCleanup(&ctrlHandlePtr->rmt.recovery);
  643.     Fsutil_HandleRemove(ctrlHandlePtr);
  644.     fs_Stats.object.controls--;
  645.     } else {
  646.         Fsutil_HandleUnlock(ctrlHandlePtr);
  647.     }
  648. }
  649.  
  650. /*
  651.  *----------------------------------------------------------------------
  652.  *
  653.  * FspdevControlScavenge --
  654.  *
  655.  *    See if this control stream handle is still needed.
  656.  *
  657.  * Results:
  658.  *    TRUE if the handle was removed.
  659.  *
  660.  * Side effects:
  661.  *    Will remove the handle if there is no server.
  662.  *
  663.  *----------------------------------------------------------------------
  664.  */
  665. Boolean
  666. FspdevControlScavenge(hdrPtr)
  667.     Fs_HandleHeader *hdrPtr;    /* File being encapsulated */
  668. {
  669.     register Fspdev_ControlIOHandle *ctrlHandlePtr = (Fspdev_ControlIOHandle *)hdrPtr;
  670.  
  671.     if (ctrlHandlePtr->serverID == NIL) {
  672.     Fsutil_RecoverySyncLockCleanup(&ctrlHandlePtr->rmt.recovery);
  673.     Fsutil_HandleRemove(ctrlHandlePtr);
  674.     fs_Stats.object.controls--;
  675.     return(TRUE);
  676.     } else {
  677.         Fsutil_HandleUnlock(ctrlHandlePtr);
  678.     return(FALSE);
  679.     }
  680. }
  681.